package week07.necessary.batchinsert.base;

import lombok.extern.slf4j.Slf4j;
import week07.necessary.batchinsert.entities.Orders;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author yky
 * @since 2021/8/5 12:40
 */
@Slf4j
public abstract class AbstractBatchInsertImpl implements IBatchInsert {
    /** 初始化数据*/
    private final Collection<List<Orders>> orders;

    public AbstractBatchInsertImpl(int total, int partition) {
        log.info("[批量插入]{}条数据,分批大小{}", total, partition);
        orders = partitionData(initialData(total), partition);
    }

    /**
     * 初始化批量插入数据
     *
     * @return 初始化的订单数据
     * @param total
     */
    @Override
    public List<Orders> initialData(int total) {
        return IntStream.range(1, total + 1).parallel().boxed().map(i -> {
            Orders orders = new Orders();
            orders.setUserId(i);
            orders.setTradeNo(UUID.randomUUID().toString());
            orders.setTotalFee(i);
            orders.setTradeFee(i / 10000);
            return orders;
        }).collect(Collectors.toList());
    }

    /**
     * 切割数据
     *
     * @param ordersList 订单列表
     * @param size       切割的大小
     * @return 分割的集合
     */
    @Override
    public Collection<List<Orders>> partitionData(List<Orders> ordersList, int size) {
        AtomicInteger atomicInteger = new AtomicInteger(size);
        return ordersList.parallelStream()
                .collect(Collectors.groupingBy(it -> atomicInteger.getAndIncrement() / size))
                .values();
    }

    @Override
    public void batchInsert(Consumer<Collection<List<Orders>>> consumer) {
        consumer.accept(orders);
    }

    /**
     * 获取数据库连接
     * @return
     */
    protected Connection getConnection() {
        String url = "jdbc:mysql://localhost:3306/week07";
        String user = "root";
        String pass = "root";
        try {
            return DriverManager.getConnection(url, user, pass);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
